A system on a chip or system on chip (SoC or SOC) is an integrated circuit (IC) that integrates all components of a computer or other electronic into a single chip. It may contain digital, analog, mixed-signal and radio-frequency function on a single chip substrate. A typical application for a SoC is in the area of embedded systems.
A typical SoC have a number of “blocks” including a microcontroller, microprocessor or DSP core(s), memory blocks including a selection of ROM, RAM, EEPROM and flash memory, timing blocks including oscillators and phase-locked loops, and input and/or output (I/O) interfaces. SoC also often have blocks including voltage regulators, power management systems, and “peripherals” such as counter-timers, real-time timers, power-on reset generators. Common digital interfaces include USB, FireWire, Ethernet, USART and SPI, and common analog interfaces include analog-to-digital converters (ADC) and digital-to-analog (DAC) converters.
The blocks of a SoC are connected by either a proprietary or industry-standard bus such as the AMBA bus from ARM Holdings. DMA controllers are used to route data directly between external interfaces and memory, bypassing the processor core and thereby increasing the data throughput of the SoC.
In addition to the hardware described above, a SoC includes internal software (often referred to as “firmware”) to control the microcontroller, microprocessor or DSP cores, the peripherals and the interfaces. Most SoCs are developed from pre-qualified hardware for the hardware elements described above, together with firmware drivers that control their operation. Of particular importance are the protocol stacks that drive industry-standard interfaces like USB. The hardware blocks are put together using CAD tools and the firmware modules are integrated using a software-development environment.
A SoC (a/k/a device under test or “DUT”) is verified for logical and functional correctness before being sent to foundry. This process is called functional verification and it accounts for a significant portion of the time and energy expended in the chip design life cycle. In everyday terms, functional verification attempts to answer the question “Does this proposed design do what is intended?” This is a complex task, and takes the majority of time and effort in most large electronic system design projects. Functional verification is very difficult because of the sheer volume of possible test cases that exist in even a simple design. Frequently there are more than 1080 possible tests to comprehensively verify a design—a number that is impossible to achieve in a lifetime.
The most intricate parts of the design have been traditionally checked manually by the verification engineers without the use of automation. For example, in a microprocessor, handshaking occurs between the instructions executed from the preloaded memory and the peripherals that are involved in the data transfer. That exchange of information is usually verified manually by probing for the internal signals in the design. Either the source code is checked or the waves produced from each simulation are visually inspected. This manual inspection can never be a part of an automatic regression suite, so one or more engineers must always perform this error prone task every time the device needs to be verified. This takes a long time especially if the processor has a large instruction code database and supports several peripherals based on different bus protocols.
Engineers have also employed simulation acceleration, emulation and/or a Field Programmable Gate Array (FPGA) prototype to verify and debug both hardware and software for SoC designs prior to tape out. With high capacity and fast compilation time, acceleration and emulation are powerful technologies that provide wide visibility into systems. Such technologies, however, operate slowly, on the order of MHz, which may be significantly slower (e.g. up to 100× slower) than the SoCs operating frequency. Acceleration and emulation boxes are also very large and expensive at $1M+. FPGA prototypes, in contrast, use FPGAs directly to enable engineers to validate and test at, or close to, a system's full operating frequency with real-world stimulus. Tools such as Certus are used to insert probes in the FPGA RTL that make signals available for observation. This is used to debug hardware, firmware and software interactions across multiple FPOA with capabilities similar to a logic analyzer. However, such systems are expensive and hard to automate.
Traditional approaches to verifying designs with software and hardware components typically involve writing numerous directed test cases in either “C” or assembly language. Randomization of the design's stimulus is very limited, or completely non-existent, making it difficult to achieve full range of functional coverage automatically, which limits checking the accuracy of the design, especially in obscure “corner” cases. For example, a microprocessor's complexity may reside in the fact that it is capable of supporting data transfer between several different peripherals in a non-deterministic and random fashion. In a traditional directed test-case approach, an engineer writes assembly code sequences for each desired sequence of events, translates them into data to be used in a preloaded memory file and then runs simulations would serially execute through the sequence of programmed events.
In the directed test-case methodology, test cases are hardcoded, and there is no randomization. While this manual process works, it is very labor intensive, limited and not very efficient. The engineer has to try to think of all the possible scenarios of code execution and then manually program them into multiple test-cases, resulting in a very tedious and sometimes error prone operation. Since only the sequences provided in the test-cases are verified and only one peripheral is accessed at a time, many areas of the design may be overlooked. Therefore, due to the vast functional state space, it is much more likely than not that the device will never be fully exercised using such prior art techniques. In other words, functional test coverage of the device will be low and the risk of having to redesign or “re-spin” the DUT will be high.
The legacy verification environment requires manually coding assembly code files with a sequence of instructions for a desired test. In the prior art, the file is processed by an engineer to generate a memory file which is preloaded into the environment prior to running a simulation. The preloaded file is read with a “readmemh” (read memory in hexadecimal) command for extracting its contents. Since the assembly code file contains the instructions needed to test a particular sequence, the information is not known outside of that file and reuse cannot be leveraged from peripheral to peripheral. Also, only one valid instruction sequence is tested at a time per simulation and peripheral. The same code must be replicated for each of the processor's peripherals and tests. Performing redundant work wastes an engineer's time and extends a project's schedule immeasurably. Also, random testing is not included, and the random tests may be the most powerful in catching those hard to find bugs in the microprocessor and at the fastest rate.
These and other limitations of the prior art will become apparent to those of skill in the art upon a reading of the following descriptions and a study of the several figures of the drawing.